#include "printf.h"
#include <stdint.h>
#include <stdarg.h>

// 声明UART字符输出函数（在boot.s中实现）
void uart_putc(char c);

// 向UART发送字符串
void uart_puts(const char *str) {
    if (!str) return;
    while (*str) {
        // 换行符转换为“回车+换行”（兼容终端显示）
        if (*str == '\n') uart_putc('\r');
        uart_putc(*str++);
    }
}

// 输出64位十六进制数（支持%lx、%p、%X）
void uart_puthex64(uint64_t num, int is_upper) {
    const char *digits = is_upper ? "0123456789ABCDEF" : "0123456789abcdef";
    uart_puts("0x");
    int has_output = 0; // 标记是否已输出非零数字（用于跳过前导零）

    // 64位共16个十六进制位，从最高位（第15位）到最低位（第0位）遍历
    for (int i = 15; i >= 0; i--) {
        uint8_t digit = (num >> (i * 4)) & 0xF;
        if (digit != 0 || has_output || i == 0) {
            uart_putc(digits[digit]);
            has_output = 1;
        }
    }
    // 处理全零的特殊情况
    if (!has_output) uart_putc('0');
}

// 输出64位十进制数（支持%ld）
void uart_putdec64(int64_t num) {
    if (num < 0) {
        uart_putc('-');
        num = -num;
    }
    uint64_t u_num = (uint64_t)num;
    char buf[21] = {0}; // 64位无符号数最大十进制长度为20位
    int idx = 0;

    // 特殊情况：数字为0
    if (u_num == 0) {
        uart_putc('0');
        return;
    }

    // 从低位到高位存入缓冲区（逆序）
    while (u_num > 0 && idx < 20) {
        buf[idx++] = (u_num % 10) + '0';
        u_num /= 10;
    }

    // 逆序输出缓冲区（转为正序）
    for (int i = idx - 1; i >= 0; i--) {
        uart_putc(buf[i]);
    }
}

// 格式化输出主函数
void printf(const char *format, ...) {
    va_list args;
    va_start(args, format);
    
    while (*format) {
        if (*format == '%') {
            format++;
            int is_long = 0;  // 标记是否为长整型（%ld、%lx）
            int is_upper = 0; // 标记十六进制是否大写（%X）

            // 检查长度修饰符 'l'（如 %ld、%lx）
            if (*format == 'l') {
                is_long = 1;
                format++;
            }

            // 检查十六进制大小写（%X 需大写）
            if (*format == 'X') {
                is_upper = 1;
            }

            switch (*format) {
                case 'd':  // 十进制整数（%d、%ld）
                    if (is_long) {
                        uart_putdec64(va_arg(args, int64_t));
                    } else {
                        uart_putdec64(va_arg(args, int32_t));
                    }
                    break;
                case 'x':
                case 'X':  // 十六进制整数（%x、%lx、%X）
                    if (is_long) {
                        uart_puthex64(va_arg(args, uint64_t), is_upper);
                    } else {
                        uart_puthex64(va_arg(args, uint32_t), is_upper);
                    }
                    break;
                case 'p':  // 指针（按64位十六进制输出）
                    uart_puthex64((uint64_t)va_arg(args, void*), 0);
                    break;
                case 's':  // 字符串
                    uart_puts(va_arg(args, const char*));
                    break;
                case 'c':  // 字符
                    uart_putc((char)va_arg(args, int));
                    break;
                case '%':  // 百分号本身
                    uart_putc('%');
                    break;
                default:   // 未知格式符，原样输出
                    uart_putc('%');
                    uart_putc(*format);
                    break;
            }
        } else {
            // 普通字符直接输出
            uart_putc(*format);
        }
        format++;
    }
    
    va_end(args);
}

void clear_screen(void) {
    // ANSI转义序列：\033[2J 清除屏幕，\033[H 光标移至左上角
    uart_puts("\033[2J\033[H");
}
